#ifndef _DynamicIB__H_
#define _DynamicIB__H_

template <class Type>
Type* DynamicIB<Type>::LockIB(const uint32& theLockCount, uint32 &nOffs, bool bWrite, bool bNonStalling)
{
  if (theLockCount > m_Count)
  {
    assert(false);
		CryLogAlways("Locking index buffer. Requested size too large!");
    return NULL;
  }

  if (m_bLocked)
	{
		CryLogAlways("Locking index buffer when it is already locked!");
    return m_pLockedData;
	}

  HRESULT hr = S_OK;







  if (m_pIB)
  {
#if defined (DIRECT3D9)
    if (theLockCount+m_nOffs > m_Count)
    {
#if !defined(XENON) && !defined(PS3)
      hr = m_pIB->Lock(0, theLockCount*sizeof(Type), (void **) &m_pLockedData, D3DLOCK_DISCARD);
			if (FAILED(hr))
			{
				m_pLockedData = NULL;
				return NULL;
			}



































#endif
      nOffs = 0;
      m_nOffs = theLockCount;
    }
    else
    {
#if !defined(XENON) && !defined(PS3)
      hr = m_pIB->Lock(m_nOffs*sizeof(Type), theLockCount*sizeof(Type), (void **) &m_pLockedData, D3DLOCK_NOOVERWRITE);
			if (FAILED(hr))
			{
				m_pLockedData = NULL;
				return NULL;
			}

















#endif
      nOffs = m_nOffs;
      m_nOffs += theLockCount;
    }
#elif defined (DIRECT3D10)
	  STALL_PROFILER("set index_buffer")
	  D3D11_MAP Map;
		D3D11_MAPPED_SUBRESOURCE mappedResource;
		memset(&mappedResource, 0x0, sizeof(mappedResource));
	  byte *pD;
    if (theLockCount+m_nOffs > m_Count)
    {
      Map = D3D11_MAP_WRITE_DISCARD;
      if (m_bReadWrite)
        Map = bWrite ? D3D11_MAP_WRITE : D3D11_MAP_READ;
      hr = gcpRendD3D->m_pd3dDeviceContext->Map(m_pIB, 0, Map, 0, &mappedResource);
			IF (FAILED(hr), 0) 
			{
				CHECK_HRESULT(hr);
				return NULL; 
			}
      m_pLockedData = (Type*)mappedResource.pData;
      nOffs = 0;
      m_nOffs = theLockCount;
    }
    else
    {
      Map = D3D11_MAP_WRITE_NO_OVERWRITE;
#if !defined(CAFE)
      if (m_bReadWrite && !bNonStalling) Map = bWrite ? D3D11_MAP_WRITE : D3D11_MAP_READ;
#endif
      D3D11_MAPPED_SUBRESOURCE mappedResource;
      hr = gcpRendD3D->m_pd3dDeviceContext->Map(m_pIB, 0, Map, 0, &mappedResource);
			IF (FAILED(hr), 0) 
			{
				CHECK_HRESULT(hr);
				return NULL; 
			}
      pD = (byte*)mappedResource.pData;
      m_pLockedData = (Type *)(pD + m_nOffs*sizeof(Type));
      nOffs = m_nOffs;
      m_nOffs += theLockCount;
    }



#endif
    assert(m_pLockedData != NULL);
    m_bLocked = true;
  }

  return m_pLockedData;
}

template <class Type>
void DynamicIB<Type>::UnlockIB()
{
  if ((m_bLocked) && (m_pIB))
  {
    HRESULT hr = S_OK;
#if defined (DIRECT3D9)













		hr = m_pIB->Unlock();


#elif defined (DIRECT3D10)



    gcpRendD3D->GetDeviceContext()->Unmap(m_pIB, 0);        
#endif
    assert(hr == S_OK);
    m_bLocked = false;
  }
}

template <class Type>
void DynamicIB<Type>::DiscardIB()
{
  int nInds = 1;
  uint16 *pInds = NULL;
  HRESULT hr = S_OK;

#if defined (DIRECT3D9)
#if !defined(XENON) && !defined(PS3)
  hr = m_pIB->Lock(0, nInds*sizeof(short), (void **)&pInds, D3DLOCK_DISCARD);


#endif
  hr = m_pIB->Unlock();
#elif defined (DIRECT3D10)
  STALL_PROFILER("set index_buffer");
  D3D11_MAPPED_SUBRESOURCE mappedResource;
  hr = gcpRendD3D->m_pd3dDeviceContext->Map(m_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
  pInds = (uint16*)mappedResource.pData;
  pInds += nInds;
  gcpRendD3D->m_pd3dDeviceContext->Unmap(m_pIB, 0);        
#endif
  m_nOffs = 0;
}

template <class Type>
HRESULT DynamicIB<Type>::Bind()
{
  return gcpRendD3D->FX_SetIStream(m_pIB);
}

#endif  //_DynamicIB__H_
